﻿using System;
using System.Xml;
using System.Reflection;

namespace Tomato.Allure
{
	public class AddOnInfo
	{
		private string m_name;

		public string Name
		{
			get { return m_name; }
			set { m_name = value; }
		}

		private string m_buttonTitle;

		public string ButtonTitle
		{
			get { return m_buttonTitle; }
			set { m_buttonTitle = value; }
		}

		private string m_toolTipText;

		public string ToolTipText
		{
			get { return m_toolTipText; }
			set { m_toolTipText = value; }
		}

		private int m_iconIndex;

		public int IconIndex
		{
			get { return m_iconIndex; }
			set { m_iconIndex = value; }
		}

		private string m_assemblyPath;

		public string AssemblyPath
		{
			get { return m_assemblyPath; }
			set { m_assemblyPath = value; }
		}

		private string m_typeName;

		public string TypeName
		{
			get { return m_typeName; }
			set { m_typeName = value; }
		}

		private AddOn m_instance;

		public AddOn Instance { get { return m_instance; } }

		public AddOnInfo(
			string name,
			AddOn instance,
			string buttonTitle,
			string toolTipText,
			int iconIndex,
			string assemblyPath,
			string typeName )
		{
			m_name = name;
			m_instance = instance;
			m_buttonTitle = buttonTitle;
			m_toolTipText = toolTipText;
			m_iconIndex = iconIndex;
			m_assemblyPath = assemblyPath;
			m_typeName = typeName;
		}

		public static AddOnInfo FromXmlNode( XmlNode xmlNode, bool bLoadInstance )
		{
#if true
			try
			{
				string assemblyPath = xmlNode[ "Assembly" ].InnerText;
				string typeName = xmlNode[ "ClassName" ].InnerText;

				// Update assembly path
				if( assemblyPath.LastIndexOf( @"\" ) == -1 )
				{
					Assembly containingAssembly = Assembly.GetAssembly( typeof( AddOnInfo ) );
					string containingAssemblyFilePath = containingAssembly.Location;

					assemblyPath = containingAssemblyFilePath.Substring( 0, containingAssemblyFilePath.LastIndexOf( @"\" ) ) + @"\" + assemblyPath;
				}

				AddOn addOn = null;

				if( bLoadInstance )
				{
					Assembly assembly = Assembly.LoadFrom( assemblyPath );
					if( assembly != null )
					{
						Type addInType = assembly.GetType( typeName );
						if( addInType != null )
						{
							addOn = ( AddOn )( Activator.CreateInstance( addInType ) );
						}
					}
				}

				return new AddOnInfo(
					xmlNode[ "Name" ].InnerText,
					addOn,
					xmlNode[ "ButtonText" ].InnerText,
					xmlNode[ "ToolTip" ].InnerText,
					int.Parse( xmlNode[ "Icon" ].InnerText ),
					assemblyPath,
					typeName );

			}
			catch( Exception ) { }

			return null;
#else
			try
			{
				using( StringReader stringReader = new StringReader( xmlString ) )
				{
					using( XmlTextReader xmlReader = new XmlTextReader( stringReader ) )
					{
						System.Xml.Serialization.XmlSerializer xmlSerializer = new System.Xml.Serialization.XmlSerializer( typeof( AddInMetaInfo ) );
						return ( AddInMetaInfo )( xmlSerializer.Deserialize( xmlReader ) );
					}
				}
			}
			catch( Exception exc ) { }

			return null;
#endif
		}

		public bool ReloadInstance()
		{
			try
			{
				Assembly assembly = Assembly.LoadFrom( m_assemblyPath );
				if( assembly != null )
				{
					Type addInType = assembly.GetType( m_typeName );
					if( addInType != null )
					{
						m_instance = ( AddOn )( Activator.CreateInstance( addInType ) );
					}
				}
			}
			catch( Exception )
			{
				m_instance = null;
			}

			return m_instance != null;
		}

		public override bool Equals( object obj )
		{
			AddOnInfo target = obj as AddOnInfo;
			if( target != null )
			{
				if( target.m_name == m_name )
				{
					return true;
				}

				if( target.m_assemblyPath == m_assemblyPath
					&& target.m_typeName == m_typeName )
				{
					return true;
				}
			}

			return false;
		}

		public override int GetHashCode()
		{
			return base.GetHashCode();
		}

		public string ToXmlString()
		{
			throw new NotImplementedException();
		}
	}
}
